#ifndef __syntax_compound_H__
#define __syntax_compound_H__

#include "syntax_base.h"
#include "syntax_call.h"
#include "syntax_char.h"
#include "syntax_attribute.h"

#include <list>
using namespace std;

namespace syntax_analysis
{
	enum compound_type
	{
		COMPOUND_AND,
			COMPOUND_OR,
	};
	
	class syntax_compound : public syntax
	{
	// construct
	public:
		syntax_compound() : syntax()
		{
			m_compound_type = COMPOUND_AND;
			m_child.clear();
			m_attr = NULL;
		}

		syntax_compound( 
			compound_type type, 
			const list<syntax*> &child,  
			syntax_attribute *attr )
		{
			m_compound_type = type;
			m_child = child;
			m_attr = attr;
		}

		virtual ~syntax_compound()
		{
			if( m_attr != NULL )
				delete m_attr;
			list<syntax*>::iterator it;
			for( it = m_child.begin(); it != m_child.end(); ++it )
				delete *it;
			m_compound_type = COMPOUND_AND;
			m_child.clear();
			m_attr = NULL;
		}

	// inherit
	public:
		virtual syntax_type get_type();
		virtual string to_string();
		
		virtual bool parse( parse_info *info );
		virtual bool reparse( parse_info *info );
		virtual bool can_accept_more( parse_para *para );
		virtual bool should_accept_more( parse_para *para );

	// common
	public:
		compound_type get_compound_type()
		{
			return m_compound_type;
		}

		void set_compound_type( compound_type type )
		{
			m_compound_type = type;
		}

		syntax_attribute* get_attr()
		{
			return m_attr;
		}

		void set_attr( syntax_attribute *attr )
		{
			if( m_attr != NULL )
				delete m_attr;
			m_attr = attr;
		}

		const list<syntax*>& get_child()
		{
			return m_child;
		}

		void set_child( const list<syntax*> &child )
		{
			list<syntax*>::iterator it;
			for( it = m_child.begin(); it != m_child.end(); ++it )
				delete *it;
			m_child = child;
		}

		syntax* get_child( int pos )
		{
			list<syntax*>::iterator it = m_child.begin();
			if( pos > m_child.size() )
				return NULL;

			advance( it, pos );
			if( it != m_child.end() )
				return *it;
			else
				return NULL;
		}

		void add_child( syntax *syn )
		{
			m_child.push_back( syn );
		}

		bool is_my_child( syntax *syn )
		{
			list<syntax*>::iterator i;
			for( i = m_child.begin(); i != m_child.end(); ++i )
			{
				if( *i == syn )
					return true;
			}
			return false;
		}

	protected:
		virtual bool do_parse( parse_info *info );

	private:
		compound_type m_compound_type;
		list<syntax*> m_child;
		syntax_attribute *m_attr;
	};

}

#endif // __syntax_compound_h__
